#!/usr/bin/python

import re
import subprocess
import socket
import xml.etree.cElementTree as et
import sys

#There are several data that will need to be created that were generated in measure_latency.py
# - NodeMapping
# - 
node_mapping = dict()
nm_f = open('node_mapping', 'r')
for line in nm_f:
    node_num = int(re.search('^(\d+)', line).group(0))
    #print node_num
    node_hostname = re.search('(?<=\s)(.+?)\s', line).group(0)
    #print node_hostname
    node_ip = re.search('([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', line).group(0)
    #print node_ip
    node_mapping[node_num] = (node_hostname, node_ip)
nm_f.close()
print node_mapping
#call ./HREA graph_file k -paths -tdijkstra
#K = 100
n = len(node_mapping)
cmd = "./kshort/HREA " + sys.argv[1] + " " + argv[2] + " -paths -tdijkstra " + str(n)
print cmd
chains_output = subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True).communicate()[0]

#print "Chains OUTput:"
#print chains_output

#grab paths, each as (delay, path)
#need to exclude paths with loops
re_match_paths = "(?:-\d+)+-\s+\(Cost:\s\d+\)"
chains_output_filtered_paths = re.findall(re_match_paths, chains_output)

#build a list of all paths for each node, with delay as key
#dict ip dest_node -> delay -> path
node_path_map = dict()
for raw_path in chains_output_filtered_paths:
    path_cost = re.search("\d+(?=\))", raw_path).group(0)
    path = re.search("(\d+-)+", raw_path).group(0).split('-')[:-1]
    dest_node = path[0]
    if dest_node not in node_path_map:
        node_path_map[dest_node] = dict()
    node_path_map[dest_node][path_cost] = path
print '\nNode PAth Map'
print node_path_map
    
#grab dest_node/delay pairs for MVC
re_match_mvc = "Delay\s:.*\n"
chains_output_filtered_mvc = re.findall(re_match_mvc, chains_output)
dest_node_delay_pairs = []
for line in chains_output_filtered_mvc:
    temp_delay = re.search("(?<=Delay\s:\s)\d+", line).group(0)
    temp_dest = re.search("(?<=Destination\s)\d+", line).group(0)
    dest_node_delay_pairs.append((temp_dest, temp_delay))
print '\nNode Dest DElays'
print dest_node_delay_pairs
    
#get final list of paths
final_paths = []
for pair in dest_node_delay_pairs:
    final_paths.append(node_path_map[pair[0]][pair[1]])
print '\nFinal paths'
print final_paths

#find node dest/next hop pairs
#node -> [(dest1,next hop), (dest2,next hop),...]
final_table = dict()
#print '\nKey/Value Mappings of nodes'
#print node_mapping.items()
for node in range(1, len(node_mapping)+1):
    temp_host = node_mapping[node][1]
    final_table[temp_host] = []
    #print node_mapping[node]
    for path in final_paths:
        print 'Processing Path'
        print path
        temp_dest = node_mapping[int(path[0])][1]
        print 'Temp Dest Hop ', temp_dest
        temp_str = str(node)
        if temp_str in path[1:]:
            temp_index = path.index(temp_str)-1
            #print('Node ', node, ' found at index ', temp_index)
            
            temp_next_hop = node_mapping[int(path[temp_index])][1]
            #print 'Temp Next Hop ', temp_next_hop
            temp_tuple = (temp_dest, temp_next_hop)
            print 'Add Final Table Entry ', temp_host, ': ',temp_tuple
            final_table[temp_host].append(temp_tuple)
print '\nFinal Table'
print final_table

#build xml do for each node in graph
#the initial set is common

#
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)



for key, value in final_table.iteritems():
    table = et.Element('table')
    source_node = et.SubElement(table, 'source_node')
    source_node.attrib['broadcast_node'] = node_mapping[1][1]
    for pair in value:
        temp_node = et.SubElement(source_node, "destination_node")
        temp_node.attrib['next_hop'] = pair[1]
        temp_node.text = pair[0]#should capture ips for each node
        
    xml_table = et.tostring(table)
    print xml_table
    s.sendto('0' + xml_table, (key, PORT))
        




